﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Threading.Tasks;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Threading;
using Wy.JiZhangSoft.ZhangDans;
using System.Linq;
using Volo.Abp.Uow;
using Wy.JiZhangSoft.Users;

namespace Wy.JiZhangSoft.Backgrounds
{
    /// <summary>
    /// 账单支出统计
    /// </summary>
    public class ZhiChuStatisticWork : AsyncPeriodicBackgroundWorkerBase
    {
        /// <summary>
        /// 统计至?天前的数据
        /// </summary>
        private static int day = ZhangDanConst.StatisticMaxDay;


        public ZhiChuStatisticWork(AbpAsyncTimer timer, IServiceScopeFactory serviceScopeFactory) : base(timer, serviceScopeFactory)
        {
            // 10 分钟 * 6  
            Timer.Period = 600000;  //10 minutes       
        }

        [UnitOfWork]
        protected async override Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
        {
            Console.WriteLine("执行时间:" + DateTime.Now);
            var users = workerContext.ServiceProvider.GetRequiredService<IRepository<AppUser>>();
            foreach (var user in users)
            {
                await Run(workerContext, user.Id);
            }
            Console.WriteLine("结束时间:" + DateTime.Now);
        }

        private static async Task Run(PeriodicBackgroundWorkerContext workerContext, Guid userId)
        {
            var zhangDans = workerContext.ServiceProvider.GetRequiredService<IRepository<ZhangDan>>().Where(x => x.CreatorId == userId && x.ShouZhiType == EnumShouZhiType.支出 && !x.Classified.Contains("借出"));
            if (!zhangDans.Any())
                return;
            var now = DateTime.Now;
            // 日统计
            {
                var leiJiZhiChuStatistics = workerContext.ServiceProvider.GetRequiredService<IRepository<LeiJiZhiChuStatistics>>();
                var lastData = leiJiZhiChuStatistics.Where(x=>x.UserId==userId).OrderByDescending(x => x.CreationTime).FirstOrDefault();
                DateTime lastDataDay;
                decimal totalPrice = 0;
                if (lastData == null)
                    lastDataDay = DateTime.Parse("2000-01-01");
                else
                {
                    lastDataDay = lastData.Day;
                    totalPrice = lastData.Price;
                }

                // 限制
                var xianzhi = now.AddDays(-day);
                if (lastDataDay == xianzhi)
                {
                    goto Mohth;
                }
                if (zhangDans.Where(x => x.Date > lastDataDay && x.Date <= xianzhi.AddDays(1)).Any())
                {
                    var zhangDanGroups = zhangDans.Where(x => x.Date > lastDataDay && x.Date <= xianzhi.AddDays(1)).ToList()
                      .GroupBy(x => DateTime.Parse(x.Date.ToString("yyyy-MM-dd")))
                      .Select(x => new
                      {
                          x.Key,
                          Price = x.Sum(x => x.Price)
                      }).OrderByDescending(x => x.Key);
                    var minDate = zhangDanGroups.Min(x => x.Key);
                    while (minDate <= xianzhi)
                    {
                        var zhangDanGroup = zhangDanGroups.SingleOrDefault(x => x.Key == minDate);
                        var day = minDate;
                        var isTrue = await leiJiZhiChuStatistics.AnyAsync(x =>x.UserId==userId && x.Day == day);
                        if (!isTrue)
                        {
                            if (zhangDanGroup != null)
                                totalPrice = totalPrice + zhangDanGroup.Price;
                            await leiJiZhiChuStatistics.InsertAsync(new LeiJiZhiChuStatistics
                            {
                                UserId= userId,
                                Day = minDate,
                                Price = totalPrice,
                                JinRiXiaoFei = zhangDanGroup == null ? 0 : zhangDanGroup.Price
                            });
                        }
                        minDate = minDate.AddDays(1);
                    }
                }
                else
                {
                    if (lastData != null)
                    {
                        var minDate = lastData.Day.AddDays(1);
                        while (minDate <= xianzhi)
                        {
                            await leiJiZhiChuStatistics.InsertAsync(new LeiJiZhiChuStatistics
                            {
                                UserId = userId,
                                Day = minDate,
                                Price = totalPrice,
                                JinRiXiaoFei = 0
                            });
                            minDate = minDate.AddDays(1);
                        }
                    }
                }
            }
            // 月统计
            Mohth:
            {
                var monthLatelyZhiChuStatistics = workerContext.ServiceProvider.GetRequiredService<IRepository<MonthLatelyZhiChuStatistic>>();
                var lastData = monthLatelyZhiChuStatistics.Where(x=>x.UserId==userId).OrderByDescending(x => x.CreationTime).FirstOrDefault();
                int lastDataMonth;
                int lastDataYear;
                if (lastData != null)
                {
                    lastDataMonth = lastData.Month;
                    lastDataYear = lastData.Year;
                }
                else
                {
                    lastDataMonth = 01;
                    lastDataYear = 2020;
                }
                //if (lastData != null)
                {
                    var zhangDanGroups = zhangDans
                       .Where(x => x.Date >= DateTime.Parse(lastDataYear + "-" + lastDataMonth + "-01"))
                       .ToArray()
                       .GroupBy(x => x.Date.ToString("yyyy-MM") + "-01")
                       .Select(x => new
                       {
                           x.Key,
                           Price = x.Sum(x => x.Price)
                       });
                    foreach (var item in zhangDanGroups.OrderBy(x => x.Key))
                    {
                        var date = DateTime.Parse(item.Key);
                        var m = await monthLatelyZhiChuStatistics.SingleOrDefaultAsync(x =>x.UserId==userId && x.Year == date.Year && x.Month == date.Month);
                        if (m == null)
                            await monthLatelyZhiChuStatistics.InsertAsync(new MonthLatelyZhiChuStatistic
                            {
                                UserId=userId,
                                Year = date.Year,
                                Month = date.Month,
                                Price = item.Price
                            });
                        else
                        {
                            if (m.Price != item.Price)
                            {
                                m.Price = item.Price;
                                await monthLatelyZhiChuStatistics.UpdateAsync(m);
                            }
                        }
                    }
                }
            }
        }
    }
}